package com.test35_代理模式;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理机制
 */
public class Demo02_JdkProxy {

    public static void main(String[] args) {
        IMessage messageObject = (IMessage) new ServerProxy().bind(new MessageImpl());  // 获取代理对象
        System.out.println(messageObject.echo("沐言优拓：www.yootk.com"));
    }
}

/**
 * 核心业务接口
 */
interface IMessage {
    public String echo(String msg);
}

/**
 * 真实业务实现类
 */
class MessageImpl implements IMessage {
    @Override
    public String echo(String msg) {
        return "【ECHO】" + msg;
    }
}

/**
 * 公共的代理实现类
 */
class ServerProxy implements InvocationHandler {
    private Object target;  // 核心业务对象

    /**
     * 保存真实业务对象
     * @param target 要绑定的真实业务对象
     * @return 系统生成的代理类对象
     */
    public Object bind(Object target) {
        this.target = target;
        // 获取真实业务主题所在类对应的类加载器，因为需要分析真实业务主题接口所拥有的方法，才可以构建动态子类
        // 所有的动态代理都是基于接口的设计应用，那么此时就要获取全部的接口信息
        // 当前类为InvocationHandler接口子类，所以使用this描述的是本接口的实例化对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 参数1：代理对象实例
     * 参数2：调用代理实例上的接口方法
     * 参数3：方法参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnValue = null;
        try {
            if (this.connect()) {
                returnValue = method.invoke(this.target, args);  // 调用真实业务主题
            }
        } finally {
            this.close();
        }
        return returnValue;
    }

    public boolean connect() {
        System.out.println("【代理业务】连接远程服务器，建立消息发送通道。");
        return true;
    }

    public void close() {
        System.out.println("【代理业务】消息发送完毕，关闭远程消息通道。");
    }
}
